#pragma once

#include "Algorithm.hh"
#include "Construct.hh"
#include "Iterator.hh"
#include "TypeTraits.hh"

namespace snow
{

/**
 * @brief uninitialized_fill_n(first,n,x)
 * 从first开始，往后填n个T类型的x
 * 即调用construct(&*i,x)，构造对象
 * 
 * @tparam ForwardIterator 
 * @tparam Size 
 * @tparam T 
 * @param first 欲初始化空间的起始处
 * @param n     欲初始化空间的大小
 * @param x     初值
 * @return ForwardIterator 
 */

// is POD，交给高阶函数fill_n，char*和wchar_t*有特化版本
template <class ForwardIterator, class Size, class T>
ForwardIterator _uninitialized_fill_n_aux(ForwardIterator first,
                                          Size n, const T &x, _true_type)
{
    return fill_n(first, n, x);
    // for (; n > 0; --n, ++first) {
    //     *first = x;
    // }
    // return first;
}
// is not POD
template <class ForwardIterator, class Size, class T>
ForwardIterator _uninitialized_fill_n_aux(ForwardIterator first,
                                          Size n, const T &x, _false_type)
{
    int i = 0;
    for (; i != n; ++i) {
        construct((T *)(first + i), x);
    }
    return (first + i);
}

// 先萃取出first的value_type，然后判断是否为POD类型
template <class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first,
                                            Size n, const T &x)
{
    typedef typename _type_traits<T>::is_POD_type isPODType;
    return _uninitialized_fill_n_aux(first, n, x, isPODType());
}

/**
 * @brief uninitialized_copy(first,last,result)
 * [first,end)的内容copy到result所指处
 * 即在result处调用construct构造*first++
 * 
 * 对于char*和wchar_t*的特化版本调用memmove更有效率，这里略
 * 即默认使用memcpy
 * 
 * @tparam InputIterator 
 * @tparam ForwardIterator 
 * @param first     输入端起始
 * @param last      输入端末尾
 * @param result    指向输出端（欲初始化空间）的起始 
 * @return ForwardIterator 
 */

// is POD，调用高阶算法copy，这里直接实现，即memcpy
template <class InputIterator, class ForwardIterator>
ForwardIterator _uninitialized_copy_aux(InputIterator first, InputIterator last,
                                        ForwardIterator result, _true_type)
{
    memcpy(result, first, (last - first) * sizeof(*first));
    return result + (last - first);
}
// is not POD
template <class InputIterator, class ForwardIterator>
ForwardIterator _uninitialized_copy_aux(InputIterator first, InputIterator last,
                                        ForwardIterator result, _false_type)
{
    int i = 0;
    for (; first != last; ++first, ++i) {
        construct((result + i), *first);
    }
    return (result + i);
}
// 萃取类型，判断是否POD
template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result)
{
    typedef typename _type_traits<iterator_traits<InputIterator>::value_type>::is_POD_type isPODType;
    return _uninitialized_copy_aux(first, last, result, isPODType());
}

/**
 * @brief uninitialized_fill()
 * 对操作范围[first,last)的每个迭代器，调用construct(&*i,x)，构造对象
 * 
 * @tparam ForwardIterator 
 * @tparam T 
 * @param first     输出端起始
 * @param last      输出端末尾
 * @param x         初值x
 */

// is POD 交给高阶函数fill，char*和wchar_t*有特化版本
template <class ForwardIterator, class T>
void _uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
                             const T &x, _true_type)
{
    fill(first, last, x);
    // for (; first != last; ++first) {
    //     *first = x;
    // }
}
template <class ForwardIterator, class T>
void _uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
                             const T &x, _false_type)
{
    for (; first != last; ++first) {
        construct(first, x);
    }
}
template <class ForwardIterator, class T>
void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T &x)
{
    typedef typename _type_traits<T>::is_POD_type isPODType;
    _uninitialized_fill_aux(first, last, x, isPODType());
}

} // namespace snow